package cn.ljy.mes.service.impl;

import cn.ljy.authority.service.impl.IBaseService;
import cn.ljy.common.exception.model.MyConfirmException;
import cn.ljy.common.exception.model.MyServiceException;
import cn.ljy.common.exception.model.MyWebException;
import cn.ljy.mes.dao.mapper.MesCarTechnologyDetailMapper;
import cn.ljy.mes.dao.mapper.MesMaterialMapper;
import cn.ljy.mes.dao.mapper.WmsMaterialBatchMapper;
import cn.ljy.mes.dao.mapper.WmsMaterialInventoryMapper;
import cn.ljy.mes.model.MesMaterial;
import cn.ljy.mes.model.WmsMaterialInventory;
import cn.ljy.mes.model.query.MesCarTechnologyDetailQuery;
import cn.ljy.mes.model.query.MesMaterialQuery;
import cn.ljy.mes.model.query.WmsMaterialInventoryQuery;
import cn.ljy.mes.service.MesMaterialService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import java.io.Serializable;
import java.util.*;

@Service
//@Transactional(propagation = Propagation.REQUIRED,isolation = Isolation.DEFAULT,timeout=36000,rollbackFor= MyRollBackException.class)
@Validated//表示开启sprint的校检框架，会自动扫描方法里的@Valid（@Valid注解一般写在接口即可）
@Slf4j
public class IMesMaterialService extends IBaseService<MesMaterial, MesMaterialQuery> implements MesMaterialService {
    @Autowired
    private MesMaterialMapper mapper;
    @Autowired
    private MesCarTechnologyDetailMapper carTechnologyDetailMapper;
    @Autowired
    private WmsMaterialInventoryMapper materialInventoryMapper;
    @Autowired
    private WmsMaterialBatchMapper materialBatchMapper;

    @Override
    protected void beforeSaveOrUpdate(MesMaterial mesMaterial) {
        if(mesMaterial.getMaterialType().getId()==null){
            throw new MyWebException("验证失败：类别id不能为空");
        }
    }

    @Override
    protected void beforeSave(MesMaterial mesMaterial) {
        //设置id
        mesMaterial.setId(UUID.randomUUID().toString());
    }

    @Override
    protected void afterSave(MesMaterial mesMaterial) {
        //添加成功后，添加物料的库存。也可以通过触发器来处理，不过考虑后续用配置文件来灵活处理，没有使用。
        WmsMaterialInventory materialInventory=new WmsMaterialInventory();
        materialInventory.setMaterial(mesMaterial);
        materialInventory.setIsLock(false);
        materialInventory.setInventoryLimit(999l);
        materialInventory.setInventoryLower(0l);
        materialInventoryMapper.save(materialInventory);
    }

    @Override
    public void afterFindAll(List<MesMaterial> list) {
        for(MesMaterial mesMaterial:list){
            //添加相关关联属性
            //工序（工艺详情）数量
            MesCarTechnologyDetailQuery carTechnologyDetailQuery=new MesCarTechnologyDetailQuery();
            carTechnologyDetailQuery.setMaterial(mesMaterial);
            int carTechnologyDetailNumber=carTechnologyDetailMapper.count(carTechnologyDetailQuery);
            mesMaterial.setCarTechnologyDetailNumber(carTechnologyDetailNumber);
        }
    }

    @Override
    protected void beforeDelete(Serializable[] ids) {
        Map<String,String> errorMessageMap=new HashMap();
        List<WmsMaterialInventory> allMaterialInventories=new ArrayList<>();
        for(Serializable id:ids){
            MesMaterial material=mapper.findByIdNoRelation(id);
            if(material!=null){
                //验证物料库存中是否有商品
                WmsMaterialInventoryQuery materialInventoryQuery=new WmsMaterialInventoryQuery();
                materialInventoryQuery.setMaterial(material);
                List<WmsMaterialInventory> materialInventories=materialInventoryMapper.findAll(materialInventoryQuery);
                if(materialInventories.size()>0){
                    allMaterialInventories.addAll(materialInventories);
                    WmsMaterialInventory materialInventory=materialInventories.get(0);
                    if(materialInventory.getTotalInventory()>0){
                        errorMessageMap.put(material.getName(),String.valueOf(materialInventory.getTotalInventory()));
                    }
                }
            }
        }
        //确定是否抛出错误信息
        if(errorMessageMap.size()>0){
            throw new MyConfirmException("%s在仓库中有%s个商品存在",errorMessageMap);
        }else{//如果没有异常则先删除其余表中记录
            //删除物料库存
            materialInventoryMapper.deleteAllIn(allMaterialInventories);
        }
    }

    @Override
    protected void beforeForceDelete(Serializable[] ids) {
        for(Serializable id:ids){
            MesMaterial material=mapper.findByIdNoRelation(id);
            if(material!=null){
                //验证物料下有多少个工序（工艺详情）使用
                MesCarTechnologyDetailQuery carTechnologyDetailQuery=new MesCarTechnologyDetailQuery();
                carTechnologyDetailQuery.setMaterial(new MesMaterial(id.toString()));
                int carTechnologyDetailNumber=carTechnologyDetailMapper.count(carTechnologyDetailQuery);
                if(carTechnologyDetailNumber>0){
                    throw new MyServiceException("删除失败："+material.getName()+"下有"+carTechnologyDetailNumber+"个工序（工艺详情）在使用，无法删除");
                }
            }
        }
    }
}
